package ar.edu.utn.frre.sistop.simumem.fragments;

import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import ar.edu.utn.frre.sistop.simumem.R;
import ar.edu.utn.frre.sistop.simumem.model.Asignacion;
import ar.edu.utn.frre.sistop.simumem.model.Estado;
import ar.edu.utn.frre.sistop.simumem.model.Memoria;
import ar.edu.utn.frre.sistop.simumem.model.Particion;
import ar.edu.utn.frre.sistop.simumem.model.Proceso;
import ar.edu.utn.frre.sistop.simumem.model.Resultado;

public class ResultPagerAdapter extends PagerAdapter {

	Context mContext;
	Memoria mMemoria;
	Resultado mResultado;
	LayoutInflater mInflater;
	int mGraphWidth;
	int mGraphHeight;

	public ResultPagerAdapter(Context contexto, Resultado resultado, Memoria memoria) {
		this.mContext = contexto;
		this.mResultado = resultado;
		this.mMemoria = memoria;
	}

	@Override
	public int getCount() {
		return mResultado.getEstados().size();
	}

	@Override
	public boolean isViewFromObject(View view, Object object) {
		return view == ((LinearLayout) object);
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {

		mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View itemView = mInflater.inflate(R.layout.item_result, container, false);

		LinearLayout llGrafico = (LinearLayout) itemView.findViewById(R.id.llResult_memoryGraph);
		TextView tvListos = (TextView) itemView.findViewById(R.id.tvResult_ready);
		TextView tvTerminados = (TextView) itemView.findViewById(R.id.tvResult_finished);

		Estado estado = mResultado.getEstados().get(position);

		graficarParticiones(llGrafico, estado, mMemoria);

		tvListos.setText(estado.getListos().toString());
		tvTerminados.setText(estado.getTerminados().toString());

		container.addView(itemView);
		return itemView;
	}

	private void graficarParticiones(final ViewGroup container, final Estado estado,
			final Memoria memoria) {

		// get the container dimensions
		ViewTreeObserver viewTreeObserver = container.getViewTreeObserver();
		if (viewTreeObserver.isAlive()) {
			viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
				@SuppressWarnings("deprecation")
				@SuppressLint("NewApi")
				@Override
				public void onGlobalLayout() {
					if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
						container.getViewTreeObserver().removeGlobalOnLayoutListener(this);
					} else {
						container.getViewTreeObserver().removeOnGlobalLayoutListener(this);
					}
					mGraphWidth = container.getWidth();
					mGraphHeight = container.getHeight();

					for (Particion particion : memoria.getParticiones()) {
						RelativeLayout rlParticion = (RelativeLayout) mInflater.inflate(
								R.layout.item_results_partition, container, false);

						LinearLayout.LayoutParams partitionLayoutParams = new LinearLayout.LayoutParams(
								mGraphWidth, 0, particion.getTamano());
						rlParticion.setLayoutParams(partitionLayoutParams);

						TextView tvPartitionEnd = (TextView) rlParticion
								.findViewById(R.id.tvResultItem_partitionEnd);
						tvPartitionEnd.setText(String.valueOf(particion.getInicio()
								+ particion.getTamano() - 1));

						graficarProceso(container, rlParticion,
								obtenerProceso(estado.getAsignaciones(), particion), particion,
								estado);

						TextView tvPartitionBeggining = (TextView) rlParticion
								.findViewById(R.id.tvResultItem_partitionBeginning);
						tvPartitionBeggining.setText(String.valueOf(particion.getInicio()));

						container.addView(rlParticion);
					}
				}
			});
		}
	}

	public void graficarProceso(final ViewGroup graph, final ViewGroup container,
			final Proceso proceso, final Particion particion, final Estado estado) {

		ViewTreeObserver viewTreeObserver = container.getViewTreeObserver();
		if (viewTreeObserver.isAlive()) {
			viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
				@SuppressWarnings("deprecation")
				@SuppressLint("NewApi")
				@Override
				public void onGlobalLayout() {
					if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
						container.getViewTreeObserver().removeGlobalOnLayoutListener(this);
					} else {
						container.getViewTreeObserver().removeOnGlobalLayoutListener(this);
					}
					mGraphWidth = container.getWidth();
					mGraphHeight = container.getHeight();

					RelativeLayout rlProcess = (RelativeLayout) container
							.findViewById(R.id.rlResultItem_process);
					if (proceso != null) {

						TextView tvProcessInfo = (TextView) container
								.findViewById(R.id.tvResultItem_processInfo);
						tvProcessInfo.setText(proceso.getId()
								+ " ("
								+ obtenerAsignacion(estado.getAsignaciones(), proceso)
										.getRestante() + ")");

						TextView tvProcessEnd = (TextView) container
								.findViewById(R.id.tvResultItem_processEnd);
						tvProcessEnd.setText(String.valueOf(particion.getInicio()
								+ proceso.getTamano() - 1));

						int partitionHeight = container.getMeasuredHeight();
						long processHeight = (partitionHeight * proceso.getTamano())
								/ particion.getTamano();

						if (processHeight < tvProcessInfo.getMeasuredHeight()) {
							processHeight = tvProcessInfo.getMeasuredHeight();
						}

						RelativeLayout.LayoutParams processLayoutParams = new RelativeLayout.LayoutParams(
								mGraphWidth, (int) processHeight);
						rlProcess.setLayoutParams(processLayoutParams);
					} else {
						rlProcess.setVisibility(View.GONE);
					}
				}
			});
		}
	}

	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		((ViewPager) container).removeView((LinearLayout) object);
	}

	private Proceso obtenerProceso(ArrayList<Asignacion> asignaciones, Particion particion) {
		for (Asignacion asignacion : asignaciones) {
			if (asignacion.getParticion() == particion)
				return asignacion.getProceso();
		}
		return null;
	}

	/*
	 * private Particion obtenerParticion(ArrayList<Asignacion> asignaciones, Proceso proceso) { for
	 * (Asignacion asignacion : asignaciones) { if (asignacion.getProceso() == proceso) return
	 * asignacion.getParticion(); } return null; }
	 */

	/*
	 * private Asignacion obtenerAsignacion(ArrayList<Asignacion> asignaciones, Particion particion)
	 * { for (Asignacion asignacion : asignaciones) { if (asignacion.getParticion() == particion)
	 * return asignacion; } return null; }
	 */

	private Asignacion obtenerAsignacion(ArrayList<Asignacion> asignaciones, Proceso proceso) {
		for (Asignacion asignacion : asignaciones) {
			if (asignacion.getProceso() == proceso)
				return asignacion;
		}
		return null;
	}

}
